package com.jyw.business.ins.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jyw.business.ast.domain.dto.web.InsRecordAstPageDto;
import com.jyw.business.ast.domain.dto.web.InsTaskAstPageDto;
import com.jyw.business.ast.domain.dto.wechat.WechatInsRecordAstPageDto;
import com.jyw.business.ast.domain.dto.wechat.WechatInsTaskAstPageDto;
import com.jyw.business.ast.domain.vo.web.InsRecordAstPageVo;
import com.jyw.business.ast.domain.vo.web.InsTaskAstPageVo;
import com.jyw.business.ins.domain.InsPlan;
import com.jyw.business.ins.domain.InsTask;
import com.jyw.business.ins.domain.InsTaskItem;
import com.jyw.business.ins.domain.InsTaskRectify;
import com.jyw.business.ins.domain.dto.web.BaseInsTaskEditDto;
import com.jyw.business.ins.domain.dto.web.InsTaskItemAddDto;
import com.jyw.business.ins.domain.dto.web.RecordUnitPageDto;
import com.jyw.business.ins.domain.dto.web.TaskUnitPageDto;
import com.jyw.business.ins.domain.dto.wechat.WechatRecordUnitPageDto;
import com.jyw.business.ins.domain.dto.wechat.WechatTaskUnitPageDto;
import com.jyw.business.ins.domain.model.CreateTaskTimeRage;
import com.jyw.business.ins.domain.vo.web.*;
import com.jyw.business.ins.enums.HandleMethodEnum;
import com.jyw.business.ins.enums.InsTaskResultEnum;
import com.jyw.business.ins.mapper.InsTaskMapper;
import com.jyw.business.ins.service.*;
import com.jyw.business.obstacles.domain.ObsOrderFault;
import com.jyw.business.obstacles.domain.ObsOrderInfo;
import com.jyw.business.obstacles.domain.dto.web.BaseOrderAddDto;
import com.jyw.business.obstacles.domain.dto.wechat.WechatOrderAddDto;
import com.jyw.business.obstacles.service.IObsOrderFaultService;
import com.jyw.business.obstacles.service.IObsOrderInfoService;
import com.jyw.common.exception.ServiceException;
import com.jyw.common.utils.SecurityUtils;
import com.jyw.common.utils.bean.BeanUtils;
import com.jyw.system.domain.dto.BaseTimeDto;
import com.jyw.system.utils.ConversionUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 巡检任务Service业务层处理
 *
 * @author system
 * @date 2023-10-07
 */
@Service
public class InsTaskServiceImpl extends ServiceImpl<InsTaskMapper, InsTask> implements IInsTaskService {
    @Resource
    private InsTaskMapper insTaskMapper;

    @Resource
    private IInsTaskItemService taskItemService;

    @Resource
    private IInsTaskRectifyService rectifyService;

    @Resource
    private IInsPlanService planService;

    @Resource
    private IObsOrderFaultService orderFaultService;

    @Resource
    private IObsOrderInfoService orderInfoService;

    @Resource
    private IInsTransmitRecordService insTransmitRecordService;

    /**
     * 查询巡检任务
     *
     * @param id 巡检任务主键
     * @return 巡检任务
     */
    @Override
    public InsTask selectInsTaskById(Long id) {
        return insTaskMapper.selectInsTaskById(id);
    }

    @Override
    public InsTaskInfoVO getInfoById(Long id) {
        InsTask insTask = insTaskMapper.selectById(id);
        if (insTask != null) {
            InsTaskInfoVO insTaskInfoVO = new InsTaskInfoVO();
            BeanUtils.copyProperties(insTask, insTaskInfoVO);
            //转交任务
            List<InsTransmitRecordVO> recordList=insTransmitRecordService.queryListByTaskId(id);
            if(CollectionUtil.isNotEmpty(recordList)){
                insTaskInfoVO.setTransmitRecordList(recordList);
            }
            //巡检任务巡检项
            List<InsTaskItemVO> taskItemList=taskItemService.findListByTaskId(id);
            if(CollectionUtil.isNotEmpty(taskItemList)){
                insTaskInfoVO.setTaskItemList(taskItemList);
            }
            //未巡检
            if(!insTaskInfoVO.getIsInspect()){
                LocalDateTime insEndTime=insTaskInfoVO.getInspectEndTime();
                LocalDateTime endTime=insEndTime.plusDays(insTaskInfoVO.getGraceDay());
                if(endTime.isAfter(LocalDateTime.now())){
                    //已超时
                    insTaskInfoVO.setState(1);
                }else{
                    //待巡检
                    insTaskInfoVO.setState(0);
                }
            }
            InsPlanInfoVO insPlanInfo=planService.selectInfoPlanById(insTask.getPlanId());
            if(insPlanInfo!=null){
                insTaskInfoVO.setCode(insPlanInfo.getCode());
                insTaskInfoVO.setName(insPlanInfo.getName());
                insTaskInfoVO.setWorkOrder(insPlanInfo.getWorkOrder());
                insTaskInfoVO.setDeadlineRectify(insPlanInfo.getDeadlineRectify());
            }
            return ConversionUtil.conversion(insTaskInfoVO,InsTaskInfoVO.class);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editInsTask(BaseInsTaskEditDto insTaskEditDto) {
        int result = insTaskEditDto.getResult();
        boolean hasAbnormal = false;
        //修改巡检项
        if (CollectionUtil.isNotEmpty(insTaskEditDto.getTaskItemList())) {
            List<InsTaskItemAddDto> taskItemList = insTaskEditDto.getTaskItemList();
            InsTaskItemAddDto addDto = taskItemList.stream().filter(a -> a.getResult().intValue() == InsTaskResultEnum.ABNORMAL.getValue()).findFirst().orElse(null);
            //巡检项存在异常
            if (addDto != null) {
                hasAbnormal = true;
            }
            taskItemList.forEach(taskItem -> {
                InsTaskItem insTaskItem = new InsTaskItem();
                BeanUtils.copyProperties(taskItem, insTaskItem);
                taskItemService.updateInsTaskItem(insTaskItem);
            });
        }
        if (hasAbnormal && InsTaskResultEnum.NORMAL.getValue() == result) {
            throw new ServiceException("巡检内容存在异常，请选择异常！");
        } else {
            //修改巡检任务
            InsTask insTask = insTaskEditDto.buildTask();
            //选择异常
            if (InsTaskResultEnum.ABNORMAL.getValue() == result) {
                if (insTaskEditDto.getHandleMethod() != null) {
                    int handleMethod = insTaskEditDto.getHandleMethod();
                    //限期整改
                    if (HandleMethodEnum.RECTIFY.getValue() == handleMethod) {
                        InsTaskRectify insTaskRectify = insTaskEditDto.buildRectify();
                        rectifyService.save(insTaskRectify);
                    }
                    //转工单
                    if (HandleMethodEnum.ORDER.getValue() == handleMethod) {
                        if (insTaskEditDto.getOrderAddDto() != null) {
                            BaseOrderAddDto orderAddDto = insTaskEditDto.getOrderAddDto();
                            ObsOrderInfo orderInfo = orderFaultService.add(insTaskEditDto.getOrderAddDto());
                            String transferOrder = JSON.toJSONString(orderAddDto);
                            String orderNum = orderInfo.getOrderNum();
                            insTask.setOrderNum(orderNum);
                            insTask.setTransferOrder(transferOrder);
                        } else {
                            throw new ServiceException("获取转工单信息异常！");
                        }
                    }
                } else {
                    throw new ServiceException("巡检内容存在异常，请选择异常处理办法！");
                }
            }
            insTaskMapper.updateInsTask(insTask);
        }
    }

    @Override
    public List<InsRecordAstPageVo> recordAstList(InsRecordAstPageDto dto) {
        List<InsRecordAstPageVo> list = insTaskMapper.recordAstList(dto);
        return ConversionUtil.conversionList(list, InsRecordAstPageVo.class);
    }

    @Override
    public List<InsRecordAstPageVo> wxRecordAstList(WechatInsRecordAstPageDto dto) {
        List<InsRecordAstPageVo> list = insTaskMapper.wxRecordAstList(dto);
        return ConversionUtil.conversionList(list, InsRecordAstPageVo.class);
    }

    @Override
    public List<RecordUnitPageVo> recordUnitList(RecordUnitPageDto dto) {
        List<RecordUnitPageVo> list = insTaskMapper.recordUnitList(dto);
        return ConversionUtil.conversionList(list, RecordUnitPageVo.class);
    }

    @Override
    public RecordDetailVo detail(Long id) {
        InsTask task = getById(id);
        RecordDetailVo vo = new RecordDetailVo(task);
        if (ObjectUtils.isEmpty(task)) {
            throw new ServiceException("记录不存在");
        }
        //获取巡检对象信息
        InsObjInfo objInfo = planService.getObjInfo(task.getPlanId());
        //根据整改方式查询内容
        if (!ObjectUtils.isEmpty(task.getHandleMethod())) {
            if (1 == task.getHandleMethod()) {
                //判断是否是限期整改
                InsTaskRectify rectify = rectifyService.lambdaQuery().eq(InsTaskRectify::getTaskId, task.getId()).one();
                vo.setTaskRectify(rectify);
            } else if (2 == task.getHandleMethod()) {
                //根据工单号获取工单信息
                ObsOrderInfo orderInfo = orderInfoService.getInfoByOrderNum(vo.getOrderNum());
                //获取报修信息
                ObsOrderFault orderFault = orderFaultService.getFaultByOrder(vo.getOrderNum());
                //封装返回信息
                WechatOrderAddDto wechatOrderAddDto = JSONObject.parseObject(task.getTransferOrder(), WechatOrderAddDto.class);

                vo.setTransferOrderInfo(orderInfo, orderFault, wechatOrderAddDto);

            }

        }
        //查询巡检内容
        List<TaskItemVo> taskItemVos = taskItemService.listByTaskId(task.getId());
        vo.setTaskItemVoList(taskItemVos);
        vo.setObjInfo(objInfo);
        return ConversionUtil.conversion(vo, RecordDetailVo.class);
    }

    @Override
    public List<RecordUnitPageVo> wxRecordUnitList(WechatRecordUnitPageDto dto) {
        List<RecordUnitPageVo> list = insTaskMapper.wxRecordUnitList(dto);
        return ConversionUtil.conversionList(list, RecordUnitPageVo.class);
    }

    @Override
    public List<InsTaskAstPageVo> taskAstList(InsTaskAstPageDto dto) {
        List<InsTaskAstPageVo> list = insTaskMapper.taskAstList(dto);
        return ConversionUtil.conversionList(list, InsTaskAstPageVo.class);
    }

    @Override
    public List<TaskUnitPageVo> taskUnitList(TaskUnitPageDto dto) {
        List<TaskUnitPageVo> list = insTaskMapper.taskUnitList(dto);
        return ConversionUtil.conversionList(list, TaskUnitPageVo.class);
    }

    @Override
    public List<InsTaskAstPageVo> wxTaskAstList(WechatInsTaskAstPageDto dto) {
        List<InsTaskAstPageVo> list = insTaskMapper.wxTaskAstList(dto);
        return ConversionUtil.conversionList(list, InsTaskAstPageVo.class);
    }

    @Override
    public List<TaskUnitPageVo> wxTaskUnitList(WechatTaskUnitPageDto dto) {
        List<TaskUnitPageVo> list = insTaskMapper.wxTaskUnitList(dto);
        return ConversionUtil.conversionList(list, TaskUnitPageVo.class);
    }

    @Override
    public List<HomeMineTaskVO> mineTask(BaseTimeDto baseTimeDto) {
        List<HomeMineTaskVO> list = this.insTaskMapper.mineTask(baseTimeDto, SecurityUtils.getUserId());
        list.add(new HomeMineTaskVO(list.stream().mapToInt(HomeMineTaskVO::getCount).sum()));
        return list;
    }

    @Override
    public List<HomeMineRectifyVO> mineRectify(BaseTimeDto baseTimeDto) {
        List<HomeMineRectifyVO> list = this.insTaskMapper.mineRectify(baseTimeDto, SecurityUtils.getUserId());
        list.add(new HomeMineRectifyVO(list.stream().mapToInt(HomeMineRectifyVO::getCount).sum()));
        return list;
    }

    @Override
    public HomeInsToDoVO todo() {
        Integer task = this.insTaskMapper.todoTask(SecurityUtils.getUserId());
        Integer rectify = this.insTaskMapper.todoRectify(SecurityUtils.getUserId());
        return new HomeInsToDoVO(task, rectify);
    }

    @Override
    public void createInsTask(InsPlan insPlan, List<InsPlanItemVO> planItems, List<CreateTaskTimeRage> timeRages) {
        if(insPlan!=null&& CollUtil.isNotEmpty(timeRages)){
            Long planId=insPlan.getId();
            Long inspectUserId=insPlan.getInspectUserId();
            int graceDay=insPlan.getGraceDay()==null?0 :insPlan.getGraceDay();
            timeRages.forEach(timeRage->{
                InsTask insTask=new InsTask();
                insTask.setPlanId(planId);
                insTask.setInspectUserId(inspectUserId);
                insTask.setInspectStartTime(timeRage.getStartTime());
                insTask.setInspectEndTime(timeRage.getEndTime());
                insTask.setGraceDay(graceDay);
                insTask.setIsInspect(false);
                insTask.setCreateTime(LocalDateTime.now());
                this.save(insTask);
                if(CollUtil.isNotEmpty(planItems)){
                    Long taskId=insTask.getId();
                    List<InsTaskItem> taskItems=new ArrayList<>();
                    planItems.forEach(planItem->{
                        InsTaskItem insTaskItem=new InsTaskItem();
                        insTaskItem.setTaskId(taskId);
                        insTaskItem.setConfigItemId(planItem.getConfigItemId());
                        insTaskItem.setSort(planItem.getSort());
                        taskItems.add(insTaskItem);
                    });
                    taskItemService.saveBatch(taskItems);
                }
            });
        }
    }

    @Override
    public void deleteCreateTask(Long planId, LocalDateTime currentTime) {
        this.insTaskMapper.deleteCreateTask(planId,currentTime);
    }
}
